 /**
 * @file     xm_client.c
 * @brief    the main process of terminal device
 * @details  1) connect the server .
 *		     2) Authenticate by server
 *               3) transfer sim data with server
 *               4) control the local module to complate 3G-WiFi converter
 *               5) process the fairs from local module
 * @date
 * @version  A001
 * @par
 *
 * @par History:
 *   version: V0.1
 */
//#include <android/log.h>
#include <signal.h>
#include <stdatomic.h>
#include "socket_base.h"
 #include "p_lib.h"
#include "pub.h"
#include "access_auth.h"
#include "file_request.h"
#include "xm_client.h"
#include "sim_main_process.h"
#include "server_connect.h"

#include "common.h"



 int HeartBeatOn = 0;
int Deal_ret_old_flag = 0;//add by lk 20151208
Sys_Ctl_t SysCtl;
 extern File_List SimFileTab[];
void HeartBeat_Set(int val);

/*
reconnect server before tt,
*/
int TT_ReconnectServer(int *iTimeoutRemain, int SigNum)
{
	int sock_fd = -1;
	int timeout = *iTimeoutRemain;
	time_t start, end;
	start = time(NULL);

	DBUG( "%s %s:%d 3G strength:%d, timeout:%d\n", __func__, SysCtl.ServerInfo.IP[0], SysCtl.ServerInfo.Port[0], 28, timeout);
	if(timeout > 1)
	{
		sock_fd = TCP_ConnectToServerTimeout(SysCtl.ServerInfo.IP[0], SysCtl.ServerInfo.Port[0], timeout);
		if((ECONNREFUSED == errno) && (SIGRTMIN == SigNum))
		{
			return 0;
		}
	}

	end = time(NULL);
	*iTimeoutRemain = timeout - (end - start);

	return sock_fd;
}

/**
 * Brief description:
    record the  information of software vertion
 * Detail description:
 * @param[in] none
 * @param[out]  None
 * @retval  None
 *
 * @par None
 *
 * @par
 *
 * @par
 *
 */

int sockReconnectCNF(int sockfd, Sys_Ctl_t *ctl)
{
	int iLen = 0;
	unsigned char sendBuf[64] = {0};
	unsigned char recvBuf[64] = {0};
	heartBeatWithData_t HBpack;
	memset(&HBpack , 0, sizeof(heartBeatWithData_t));

	TD_ComProtocl_SendFrame_t *p_send = (TD_ComProtocl_SendFrame_t *)sendBuf;
	TD_ComProtocl_RecvFrame_t * p_recv = (TD_ComProtocl_RecvFrame_t *)recvBuf;

	if(ctl->AA_Result.ErrCode == LoginSuccess) //add by 20160510
		memcpy(HBpack.IMSI, ctl->AA_Result.AA_OK.imsi, 9);

	memcpy(HBpack.SN, ctl->AA_Info.SN, 16);
	HBpack.FirmWareVer = ctl->AA_Info.FirmwareVer;

	p_send->Cmd_TAG = TAG_HEARTBEAT;
	p_send->FrameSize = sizeof(heartBeatWithData_t);

	memcpy(p_send->Frame_Data, &HBpack, sizeof(heartBeatWithData_t));
	//Debuf_Print_Data (sendBuf, 2 + p_send->FrameSize, "[sockReconnectCNF]:send imsi and sn to server\n");
	iLen = TCP_SendMessage(sockfd, sendBuf, 2 + p_send->FrameSize);

	DBUG( "[sockReconnectCNF]:%d bytes send\n", iLen);

	return 1;
}

///////////////////////////////////////////add by lk 20150612///////////////////////
int Vsim_Logout_Pack(unsigned char *Dst)
{
    Vsim_Logout Src;
    TD_ComProtocl_SendFrame_t *p_dst = (TD_ComProtocl_SendFrame_t *)Dst;

    if( NULL == Dst )
    {
        return -1;
    }

    memcpy(Src.Imsi, SysCtl.AA_Result.AA_OK.imsi, 9);
    memcpy(Src.SN, SysCtl.AA_Info.SN, 16);
	//DBUG( "SN=%s\n",SysCtl.AA_Info.SN);
    p_dst->Cmd_TAG = TAG_LOGOUT_CMD;
    memcpy(p_dst->Frame_Data, &Src, sizeof(Vsim_Logout));
	p_dst->FrameSize = sizeof(Vsim_Logout);

	return (2 + p_dst->FrameSize);
}

int Send_Logout_Pack_To_Server(int Flag)
{
	int Snd_Len;
	unsigned char SndBuff[NORMAL_BUFF_MAX]={0};

	DBUG( "@@@@@@@@@ send logout to server, device will power off @@@@@@@@@\n");
	Snd_Len = Vsim_Logout_Pack(SndBuff);
	if(SysCtl.Sockfd < 0)
	{
		DBUG( "############# [logout TCP_ConnectToServerTimeout] #############\n");
		SysCtl.Sockfd = TCP_ConnectToServerTimeout(SysCtl.ServerInfo.IP[0], SysCtl.ServerInfo.Port[0], 5);
	}

	if(SysCtl.Sockfd > 0)
	{
		if(send(SysCtl.Sockfd, (char *)SndBuff, Snd_Len, 0) < 0)
		{
			DBUG( "@@@@@@@@@ but send fail @@@@@@@@@\n");
			close(SysCtl.Sockfd);
			SysCtl.Sockfd = -1;
		    return -5;
		}

		DBUG( "@@@@@@@@@ send ok @@@@@@@@@\n");
		sleep(5);
		close(SysCtl.Sockfd);
		SysCtl.Sockfd = -1;
	}

	return 0;
}
////////////////////////////////////////////end////////////////////////////////////////////////

int AplicationGetIpPortByDNS(char *DomainName, char *ServerIP, int *piServerPort)
{
	struct hostent *host;
	DBUG( "DNS analysis to %s", DomainName);
	DBUG( "the ip get by dns is %s", ServerIP);

	return 0;
}

void AA_to_SysCtl(Sys_Ctl_t * ctl)
{
	ctl->DayMinutesRemain = ctl->AA_Result.AA_OK.minute_Remain;

	if((0 < ctl->AA_Result.AA_OK.Data_Clr_Flag) || (1440 == ctl->AA_Result.AA_OK.minute_Remain))
	{
		DBUG( "!!!!!!!!!!!!!!Need to Clr local data day used!!!!!!!!!!!!!!!!!!\n");
		ctl->bandWidthCtlExeFlag = 1;
		//Set_Data_Day_Used("0", DATA_USED_CNT_FILE);
	}

	return;
}
//AplicationAuthWithServer(SysCtl.Sockfd, &(SysCtl.AA_Info), &SysCtl.AA_Result);
int AplicationAuthWithServer(int socketfd, AccessAuth_Def *Src, AccessAuth_Result_t *Dst)//modify by lk 20150518(add para int len)
{
	int step = 0;
	int status = 0;
	int len = 0;
	static int i = 1;
	TD_ComProtocl_RecvFrame_t Temp;
	Sys_Ctl_t *p_SysCtl = &SysCtl;
	memset((unsigned char *)(&Temp), 0, sizeof(TD_ComProtocl_RecvFrame_t));

	status = TCP_AccessAuth_Main(socketfd, Src, &Temp, &len);
	switch(status)
	{
		case ACCESS_AUTH_FINISH:
			switch(AccessAuth_Result_ANL(&Temp, Dst, len))
			{
				case LOGIN_RSP_OK:
				{
					DBUG("++++++++++++++++Login server success++++++++++++++\n");
					memcpy(&(p_SysCtl->AA_Result), Dst, sizeof(AccessAuth_Result_t));
					AA_to_SysCtl(p_SysCtl);
					//SetCWL_Sta(CWL_DeliverServerInfo);//modify by 20161118
					step = 3;
					break;
				}
				case LOGIN_RSP_TAG_ERROR:
					p_SysCtl->AA_Result.ErrCode = Dst->ErrCode;//add by lk 20151201
					sleep(2);
					step = 2;
					break;

				case LOGIN_RSP_ERROR_CODE: // server returned err_code
					HeartBeat_Set(1);
					if(SysCtl.Power_off_ing_flag == 0) // add by zhangly
					{
						if(Dst->ErrCode == 4) //no vsim led1 yellow
						{

						}
						else // the error code led1 red
						{

						}
					}
					step = 8; //add by lk 20150903
					p_SysCtl->AA_Result.ErrCode = Dst->ErrCode;//add by lk 20151201
					break;

				case LOGIN_RSP_JUMP://add by lk Change IP ??
				{
					TD_ComProtocl_RecvFrame_t *p_AA_Result = &Temp;
					Server_Port_Ip para;
					memset(&para, 0, sizeof(Server_Port_Ip));
					DBUG( "MipList from server is %s\n", p_AA_Result->Frame_Data + 1);

					if(0 == DstANL_IP((char *)(p_AA_Result->Frame_Data + 1), &para))
					{
						memcpy(&SysCtl.ServerInfo, &para, sizeof(para));
						//if(!SetServerInfo(&para))//add by lk 20150518
						//{
						//	TCP_IP_Main(socketfd);//add by lk 20150518
						//	sleep(2);//add by lk 20150518
						//	step = 0;//add by lk 20150528
						//}
					}
					break;
				}
			}

			if(i != 1)
				i = 1;

			break;
        case ACCESS_AUTH_FAIL_RECV_ERRO:
			if(SysCtl.Power_off_ing_flag == 0) //add by  zhangly
			{

			}
            sleep(30 * i);
            i = i * 2;
            DBUG( "The i is %d\n", i);
			step = 2;
			break;
        case ACCESS_AUTH_FAIL_SEND_ERRO:
		default:
			sleep(1);
			step = 0;//add by lk 20150528
			break;
	}

	return 0;
}

int Set_MAIN_STAGE_AA_WITH_SERVER(int socketfd)
{
	Close_Socket(&socketfd);

	return 0;
}

int AplicationAutoDialerNumGet(int socketfd, AccessAuth_Result_t *AA_Result, Sys_Ctl_t *ctl)
{
	TD_ComProtocl_SendFrame_t SendData;
	TD_ComProtocl_RecvFrame_t RecvData;
	int status = 0;

	if(0 < AA_Result->AA_OK.Vusim_Active_Flag)
	{
		SendData.Cmd_TAG = TAG_ADN;
		SendData.FrameSize = 0;
		status = TCP_SendMessage(socketfd, (unsigned char *)(&SendData), 2 + SendData.FrameSize);
		if(status <= 0)
		{
			DBUG( "[AplicationAutoDialerNumGet]: send error %d,restart\n", status);
			Set_MAIN_STAGE_AA_WITH_SERVER(socketfd);
			return -1;
		}

		status = TCP_RecvMessage(socketfd, (unsigned char *)(&RecvData), 0, MSG_WAITALL, 30);
		if(status <= 0)
		{
			DBUG( "[AplicationAutoDialerNumGet]: recv error %d,restart\n", status);
			Set_MAIN_STAGE_AA_WITH_SERVER(socketfd);
			return -2;
		}

		memset(ctl->AutoDialerNum, 0, NORMAL_BUFF_LEN);//add by lk 20151125
		memcpy(ctl->AutoDialerNum, RecvData.Frame_Data, RecvData.FrameSizeL);
		ctl->autoDialerFlag = 1;
		DBUG( "AutoDialerNum from server is %s\n", ctl->AutoDialerNum);
	}

	return 0;
}

int AplicationGetAPNinfo(int socketfd, Sys_Ctl_t *ctl)
{
	TD_ComProtocl_SendFrame_t SendData;
	TD_ComProtocl_RecvFrame_t RecvData;
	int iTemp = 0;

	if(0x01 == (0x01&(ctl->AA_Result.AA_OK.Unused[0])))
	{
		SendData.Cmd_TAG = TAG_GET_APN_INFO;
		SendData.FrameSize = 0;
		iTemp = TCP_SendMessage(socketfd, (unsigned char *)(&SendData), 2);
		if(iTemp <= 0)
		{
			DBUG( "[AplicationGetAPNinfo]:send error %d,restart\n", iTemp);
			Set_MAIN_STAGE_AA_WITH_SERVER(socketfd);
			return -2;
		}

		iTemp = TCP_RecvMessage(socketfd, (unsigned char *)(&RecvData), 0, MSG_WAITALL, 30);
		if(iTemp <= 0)
		{
			DBUG( "[AplicationGetAPNinfo]:recv error %d restart\n", iTemp);
			Set_MAIN_STAGE_AA_WITH_SERVER(socketfd);
			return -3;
		}

		memset(ctl->APN_Info, 0, NORMAL_BUFF_LEN);//add by ywy 20151125
		memcpy(ctl->APN_Info, RecvData.Frame_Data, RecvData.FrameSizeL);
		ctl->APN_deliverFlag = 1;
		DBUG( "[AplicationGetAPNinfo]:apn from server is %s\n", ctl->APN_Info);
	}

	return 0;
}

int AplicationGetMSNinfo(int socketfd, Sys_Ctl_t *ctl)
{
	TD_ComProtocl_SendFrame_t SendData;
	TD_ComProtocl_RecvFrame_t RecvData;
	int iTemp = 0;

	if(0x02 == (0x02&(ctl->AA_Result.AA_OK.Unused[0])))
	{
		SendData.Cmd_TAG = TAG_AUTONET;
		SendData.FrameSize = 0;
		iTemp = TCP_SendMessage(socketfd, (unsigned char *)(&SendData), 2);
		if(iTemp <= 0)
		{
			DBUG( "[AplicationGetMSNinfo]:send error %d,restart\n", iTemp);
			Set_MAIN_STAGE_AA_WITH_SERVER(socketfd);
			return -2;
		}

		iTemp = TCP_RecvMessage(socketfd, (unsigned char *)(&RecvData), 0, MSG_WAITALL, 30);
		if(iTemp <= 0)
		{
			DBUG( "[AplicationGetMSNinfo]:recv error %d restart\n", iTemp);
			Set_MAIN_STAGE_AA_WITH_SERVER(socketfd);
			return -3;
		}

		//SetMSN((char *)(RecvData.Frame_Data), RecvData.FrameSizeL);
		ctl->MSN_deliverFlag = 1;
		DBUG( "[AplicationGetMSNinfo]:MSN from server is %s\n", RecvData.Frame_Data);
	}

	return 0;
}

int AplicationLocalFileUpdate(int socketfd, AccessAuth_Result_t *AA_Result)
{
	int step = 7;
	int status = 0;


	DBUG( "Updating SimFiles...\n");
	status = SimFileRequest_main(socketfd, AA_Result);
	if(status == SIM_FILE_CHECK_ERR)
	{
		DBUG( "error occured during requesting simfiles\n");
		step = 2;//modify by 20160523
	}
	else
		DBUG( "Update simfiles success!\n");

	return 0;
}

static int AplicationProtocolANL_Prepare(AccessAuth_Result_t *AA_Result, char *SN)
{
	char sIMSI[32];
	File_List * p_list = SimFileTab;
	TT_Data Para;

	memset(sIMSI, 0, sizeof(sIMSI));
	memset(&Para, 0, sizeof(TT_Data));
	Hex2String(AA_Result->AA_OK.imsi, sIMSI, 9);

	//Debuf_Print_Data(SysCtl.AA_Result.AA_OK.imsi, 9, "The imsi is:");
	Para.SN = atoi(SN + 6);
	Para.Port = AA_Result->AA_OK.byteRemain;
	Para.system_id = AA_Result->AA_OK.system_id;
	Para.channel_id = AA_Result->AA_OK.channel_id;
	Para.IP[0] = AA_Result->AA_OK.IP[0];
	Para.IP[1] = AA_Result->AA_OK.IP[1];
	Para.IP[2] = AA_Result->AA_OK.IP[2];
	Para.IP[3] = AA_Result->AA_OK.IP[3];

	Set_IMSI_Para(AA_Result->AA_OK.imsi, &Para);

	return 0;
}

int TT_Process_t(Sys_Ctl_t *ctl)
{
	int val = 0;
	ctl->Apdu_Cnt++;
	memset(ctl->TT_Buf, 0, sizeof(ctl->TT_Buf));

	val = GetVisualSIM_TT_Data(ctl->TT_Buf, &(ctl->TT_cnt));
	if(val > 128)
		val = 128;

	DBUG( "TTTTTTTTTTTTTTTTTTTT num=%d, Sockfd is %d TTTTTTTTTTTTTTTTTTTTT\n", ctl->TT_cnt, ctl->Sockfd);

	if((ctl->Apdu_Cnt > TT_MAX_NUM) || (ctl->Sockfd <= 0))
	{
		DBUG( "Apdu_Cnt:%d > %d\n", ctl->Apdu_Cnt, TT_MAX_NUM);
		goto err;
	}

	val = send(ctl->Sockfd, ctl->TT_Buf, val, 0);
	if(val <= 0)
	{
		DBUG( "%s Snd error, the val is %d, the err is %d:%s\n", __func__, val, errno, strerror(errno));
err:
		Close_Socket(&ctl->Sockfd);
		SetTT_Snd_Sta(ctl->TT_cnt, TT_Snd_Err);
		return -3;
	}

	PrintDebuf("[TCP_CmdTransferTransparent]:data send to server is: ", ctl->TT_Buf, val);
	ctl->TT_flag = 0;

	return 0;
}

int HB_New_Pack(Sys_Ctl_t *ctl, unsigned char *Dst)
{
	char sBuf[512] = {0};
	unsigned int temp = 0;
	TD_ComProtocl_SendFrame_t *p_dst = (TD_ComProtocl_SendFrame_t *)Dst;
	HB_NEW_t HB_Pack;
	HB_Pack.Local_DataUsed = ctl->LocMod.DataUsed;
	HB_Pack.Sig_Strength = 28;//Get_3g_Strength();
	HB_Pack.MCC = (unsigned short)(ctl->AA_Info.MCC);
	HB_Pack.MNC = (unsigned char )(ctl->AA_Info.MNC);
	HB_Pack.LAC = ctl->AA_Info.LAC;
	HB_Pack.CID = ctl->AA_Info.CID;

	p_dst->Cmd_TAG = TAG_HB_NEW;
	p_dst->FrameSize = sizeof(HB_NEW_t);
	memcpy(p_dst->Frame_Data, (unsigned char*)(&HB_Pack), sizeof(HB_NEW_t));

	return (2+p_dst->FrameSize);
}

int Deal_Pack(Sys_Ctl_t *ctl, unsigned char *Dst)
{
	TD_ComProtocl_SendFrame_t *p_dst = (TD_ComProtocl_SendFrame_t *)Dst;
	Deal_t Deal_Pack_t;
	memset(&Deal_Pack_t, 0, sizeof(Deal_t));
	p_dst->Cmd_TAG = TAG_DEAL;
	p_dst->FrameSize = sizeof(Deal_t);

	Deal_Pack_t.MCC = (unsigned short)(ctl->AA_Info.MCC);
	Deal_Pack_t.SN = atoll(ctl->AA_Info.SN);
	memcpy(Deal_Pack_t.IMSI, ctl->AA_Result.AA_OK.imsi, 9);

	DBUG("The MCC is %d, SN is %llu, sizeof(SN) is %d\n", Deal_Pack_t.MCC, Deal_Pack_t.SN, sizeof(Deal_Pack_t.SN));

	memcpy(p_dst->Frame_Data, (unsigned char*)(&Deal_Pack_t), p_dst->FrameSize);

	return (2 + p_dst->FrameSize);
}

int Deal_Data_Coding(Sys_Ctl_t *ctl)
{
	static int num = 0;
	int SendLen = 0;
	unsigned char SendBuf[256] = {'\0'};
	int len = 0;

	if(num >= 10)
	{
		DBUG( "&&&&&&&&&&&&& %s send num > 10:&&&&&&&&&&&&&\n", __func__);
		return 0;
	}

	if(ctl->Sockfd <= 0)
	{
		DBUG( "&&&&&&&&&&&&& %s send num > 10:&&&&&&&&&&&&&\n", __func__);
		return -1;
	}

	SendLen = Deal_Pack(ctl, SendBuf);
	SendLen = send(ctl->Sockfd, SendBuf, SendLen, 0);
	if(SendLen <= 0)
	{
		DBUG( "&&&&&&&&&&&&& deal data send fail,Fd:%d &&&&&&&&&&&&&\n", ctl->Sockfd);
		Close_Socket(&ctl->Sockfd);
	}

	//Debuf_Print_Data(SendBuf, SendLen, "[Deal_Data_Coding]:data send to server is: ");
	Deal_ret_old_flag = 0;
	num++;

	return 0;
}

int HeartBeat_Snd(Sys_Ctl_t *ctl)
{
	DBUG("-------------------------------------------------\n");
	int SendLen = 0;
	unsigned char SendBuf[256]={'\0'};

	if((ctl->HeartBeat_cnt >= 10) || (ctl->Sockfd <= 0) || (0 == HeartBeatOn))
	{
		Close_Socket(&ctl->Sockfd);
		return 0;
	}

	if((0 == ctl->LocMod.net_3g_sta) && (ctl->HeartBeat_cnt < 11))
	{
		(ctl->HeartBeat_cnt) ++;

		/*data package*/
		SysCtl.Heart_ret_old_flag = 0;
		SendLen = HB_New_Pack(ctl, SendBuf);



		SendLen = send(ctl->Sockfd, SendBuf, SendLen, 0);
		if(SendLen <= 0)
		{
			DBUG( "&&&&&&&&&&&&& heart beat send faild, %d:%s &&&&&&&&&&&&&\n", errno, strerror(errno));
			return -1;
		}
	}

	return 2;
}
/*
int CellDataUpdater(CellData_t *cell_data)
{
	char sBuf[512] = {0};
	char sTemp[32] = {0};

	if(File_Read(AUTH_FILE, sBuf, sizeof(sBuf)) > 0)
	{
		str_PickUp(sBuf, "MCC:", ",", sTemp);
		cell_data->MCC = atoi(sTemp);
		str_PickUp(sBuf, "MNC:", ",", sTemp);
		cell_data->MNC = atoi(sTemp);
		str_PickUp(sBuf, "LAC:", ",", sTemp);
		cell_data->LAC = atoi(sTemp);
		str_PickUp(sBuf, "CID:", ",", sTemp);
		cell_data->CID = atoi(sTemp);
		str_PickUp(sBuf, "sig_strenth:", "}", sTemp);
		cell_data->sig_strenth = atoi(sTemp);
	}

	return 0;
}

int CellDataDet(Sys_Ctl_t *ctl)
{
	CellData_t cur_CellData;
	memset(&cur_CellData, 0, sizeof(cur_CellData));
	int status = 0;

	status = CellDataUpdater(&cur_CellData);

	if((ctl->AA_Info.MCC != cur_CellData.MCC) && (0 < cur_CellData.MCC))
	{
		ctl->AA_Info.MCC = cur_CellData.MCC;
		ctl->AA_Info.MNC = cur_CellData.MNC;
		ctl->AA_Info.LAC = cur_CellData.LAC;
		ctl->AA_Info.CID = cur_CellData.CID;
		status = 1;
	}

	return status;
}
*/
void HeartBeat_Main(void)
{
	static int HeartBeat_Time = HB_INTERVAL;
	Delay(1, 0);
	HeartBeat_Time-- ;
	pid_t pid = getpid();

	if(0 == HeartBeat_Time)
	{
		HeartBeat_Time = HB_INTERVAL;

		if((0 == SysCtl.LocMod.net_3g_sta) && HeartBeatOn)
		{
			kill(pid, SIGUSR1);
		}
	}

	if(0 == (HeartBeat_Time % 5))
	{
		//if(CellDataDet(&SysCtl))//auto swap cell station
		{
			DBUG( "Country Changed\n");
		}
	}

	return;
}

void HB_Init()
{
	HeartBeatOn = 0;
	return ;
}

void HeartBeat_Set(int val)
{
	HeartBeatOn = val;
	return;
}

int Check_Socket_Valid(Sys_Ctl_t *para, int Sig)
{
	int timeout = 7;

	switch(Sig)
	{
		//case SIGRTMIN:
		//	if(para->Apdu_Cnt > TT_MAX_NUM)
		//		return -1;

		//	if(0 == para->TT_flag)
		//		goto ret;

		//	break;
		case SIGUSR1:
			if(para->HeartBeat_cnt >= 10)
				return -2;

			break;
		case SIGUSR2:
			return 0;
		default:
			break;
	}

	if(para->Sockfd <= 0)
	{
ret:
		if(para->Sockfd > 0)
		{
			Close_Socket(&para->Sockfd);
			Delay(0, 100);
		}
		para->Sockfd = TT_ReconnectServer(&timeout, Sig);
	}

	if(0 == timeout)
	{
		DBUG( "spend too much time on reconnecting server\n");
		return -1;
	}

	if((para->Sockfd <= 0))
		return -2;

	return para->Sockfd;
}

void *SocketSendThread(void *arg)
{
	Sys_Ctl_t *p_SysCtl = &SysCtl;

	int sig;
	int rc;
	sigset_t waitset, oset;
	sigemptyset(&waitset);
	sigaddset(&waitset, SIGRTMIN);
	sigaddset(&waitset, SIGUSR1);
	sigaddset(&waitset, SIGUSR2);

	p_SysCtl->TT_flag = 1;//add by 20161118

	while(1)
	{
		rc = sigwait(&waitset, &sig);
		if (rc != -1)
		{
			Check_Socket_Valid(p_SysCtl, sig);

			switch(sig)
			{
				//case SIGRTMIN://this come from TT
				//	TT_Process_t(p_SysCtl);
				//	break;
				case SIGUSR1://this come from heartbeat
					HeartBeat_Snd(p_SysCtl);
					break;
				default:
					break;
			}
		}
	}

	DBUG( "Sockfd send thread exit\n");
	pthread_exit(0);

	return NULL;
}

int DataANL(unsigned char *Src, int *len, unsigned char *Dst, int *num)
{
	int CMD = -1;
	TD_ComProtocl_RecvFrame_t * p_src = (TD_ComProtocl_RecvFrame_t * )Src;

	CMD = p_src->Cmd_TAG;
	*len = p_src->FrameSizeL;
	if(*len > 1)
	{
		*num = p_src->Result;
		memcpy(Dst, p_src->Frame_Data, *len);
	}

	return CMD;
}

void ShutDown_NetWork(Sys_Ctl_t *p_SysCtl)
{
	//Set_VSIM_ANL_StateMacine(VSIM_ANL_REMOVE);
	p_SysCtl->billStatus = 0;
	p_SysCtl->LocMod.net_3g_sta = 0;
	p_SysCtl->AA_Result.ErrCode = 2;

//////////////add by lk 20161213/////////////////////////////
	if(SysCtl.Power_off_ing_flag == 0) //add by zhangly
	{

	}
///////////////////endif////////////////////////////////////
}

int Socket_Err_Coding(void)
{
	static int interval = 0;
	static int insert_num = 0;
	Delay(0, 50);

	if(1 == SysCtl.LocMod.net_3g_sta)
	{
		SysCtl.interval = 0;
		SysCtl.Apdu_Cnt = 1;//add 20161028
	}
	else
		SysCtl.interval++;

	if((SysCtl.interval >= TIME_OUT) && (0 == SysCtl.LocMod.net_3g_sta) && (LoginSuccess == SysCtl.AA_Result.ErrCode))
	{
		SysCtl.interval = 0;
		if((insert_num == 0) && (SysCtl.Apdu_Cnt < TT_MAX_NUM))
		{
			DBUG( "\n\nIt's time to reinsert sim, the MCC is %d, insert_num is %d\n\n", SysCtl.AA_Info.MCC, insert_num);
			//Set_VSIM_ANL_StateMacine(VSIM_ANL_INSERT);
			SysCtl.Apdu_Cnt = 0;//Pass through cnt clr 0
		}
		else
			HeartBeat_Set(1);

		insert_num = 1;
	}

	return 0;
}

void *SocketRecvThread(void *arg)
{
	Sys_Ctl_t *p_SysCtl = &SysCtl;

	int temp_len = -1;
	int cnt = 0;
	int num = 0;
	int deal_num = 0;
	unsigned int CMD = 0;
	unsigned char TTRecvBuf[128];
	unsigned char Value[128] = {0};
	int minute_Remain = -1;
	TD_ComProtocl_RecvFrame_t *p_Recv = NULL;

	while(1)
	{
		switch(SysCtl.Step)
		{
			case 8:
			{
				if(SysCtl.Sockfd > 0)
				{
					memset(TTRecvBuf, 0, sizeof(TTRecvBuf));
					temp_len = recv(SysCtl.Sockfd, TTRecvBuf, sizeof(TTRecvBuf), MSG_DONTWAIT);
					if(temp_len > 0)
					{
						CMD = DataANL(TTRecvBuf, &cnt, Value, &num);
						SysCtl.interval = 0;

						switch(CMD)
						{
							case TAG_RESULT_CMDTT:
								if(cnt > 1)
								{
									DBUG( "TT:%d bytes recved now!, recv num is %d, TT_cnt is %d\n", cnt, num, p_SysCtl->TT_cnt);
									if(num == p_SysCtl->TT_cnt)
									{
										TT_Recv_Set(Value, cnt, num);
										p_SysCtl->TT_flag = 1;
									}
								}
								else if(cnt == 1)
								{
									DBUG( "TT error, The simcards is not run, Go to change vsim\n");
									//Set_VSIM_ANL_StateMacine(VSIM_ANL_REMOVE);
								}
								break;

							case TAG_HB_RET:
							case TAG_HB_NEW_RET:
								DBUG( "This come from TAG_HB_RET %d bytes\n", temp_len);
								SysCtl.Heart_ret_old_flag = 1;
								break;

							case TAG_UPDATE_LOCAL:
							case TAG_UPDATE_ROAM:
							case TAG_UPDATE_LOCAL_APK:
							case TAG_UPDATE_ROAM_APK:
							case TAG_UPDATE_MIP:
							case TAG_UPDATE_ROAM_PAPK:
								/*
								if(1 == Get_Updata_Start_Flag())
								{
									DBUG( "========== updata file doing ==========\n");
									break;
								}
								Set_Updata_Start_Flag(1);
								Updata_Soft.Updata_Type = Value[0];
								Set_Updata_File_Type(Updata_Soft.Updata_Type);
								DBUG( "updata file:%s\n", Updata_Soft.path);*/
								DBUG( "============ recv updata soft cmd,Tag: Type: ============\n");
								break;

							case TAG_SWAP_VUSIM:
								DBUG( "\n\n************************This come to swap SIM cards***********************\n\n");
								//ClrCWL_Ctl();
								break;

							case TAG_LOGOUT_CMD:
								Send_Logout_Pack_To_Server(1);
								//Roam_Will_Power_Off(2);
								DBUG( "************************This come to Roam_Will_Power_Off***********************\n");
								break;

							case TAG_DEAL_RET://add by lk 20151204
								Deal_ret_old_flag = 1;
								memcpy(&minute_Remain, Value, 4);
								DBUG( "****************The minute_Remain is %d******************\n", minute_Remain);
								break;
							case TAG_APN_CMD:
								{
									p_Recv = (TD_ComProtocl_RecvFrame_t * )TTRecvBuf;
									memset(SysCtl.APN_Info, 0, NORMAL_BUFF_LEN);
									strcpy(SysCtl.APN_Info, (char *)(p_Recv->Frame_Data));
									SysCtl.APN_deliverFlag = 1;
									DBUG("##### APN recved from server is %s #####\n",p_Recv->Frame_Data);
									//SetCWL_Sta(CWL_DeliverAPN);
								}
								break;

							case TAG_MSG_CMD:
								{
									p_Recv = (TD_ComProtocl_RecvFrame_t * )TTRecvBuf;
									memset(SysCtl.AutoDialerNum, 0, NORMAL_BUFF_LEN);
									strcpy(SysCtl.AutoDialerNum, (char *)(p_Recv->Frame_Data));
									SysCtl.autoDialerFlag = 1;
									DBUG("##### Auto dialer num recved from server is %s #####\n",p_Recv->Frame_Data);
									//SetCWL_Sta(CWL_Activate);
								}
								break;

							case TAG_AUTONET:
								{
									p_Recv = (TD_ComProtocl_RecvFrame_t * )TTRecvBuf;
									//SetMSN((char *)(p_Recv->Frame_Data),p_Recv->FrameSizeL);
									DBUG("##### ManualSelectNet info recved from server is %s #####\n",p_Recv->Frame_Data);
									//SetCWL_Sta(CWL_DeliverMSN_Info);
								}
								break;

							case TAG_SHUTDOWN_CMD:
								{
									p_Recv = (TD_ComProtocl_RecvFrame_t * )TTRecvBuf;
									DBUG("###### Remote shutdown cmd recved from server ######\n");
									Send_Logout_Pack_To_Server(1);//add by yyh 20150812
									//SetCWL_Sta(CWL_Remote_Shut_Down);
								}
								break;

							case TAG_REINSERT_VSIM_CMD:
								if(SysCtl.AA_Result.ErrCode != LoginSuccess)
									break;

								p_Recv = (TD_ComProtocl_RecvFrame_t * )TTRecvBuf;
								DBUG("###### Remote reinsert vsim cmd recved from server ######\n");
								//Set_VSIM_ANL_StateMacine(VSIM_ANL_INSERT);
								SysCtl.Apdu_Cnt = 0;//Pass through cnt clr 0
								break;
							default:
								DBUG( "Tag is %02x\n",TTRecvBuf[0]);
								break;
						}
					}
					else if(0 == temp_len)
					{
						DBUG( "This come from %s:%d, temp_len is %d, err is %d:%s\n", __func__, __LINE__, temp_len, errno, strerror(errno));
						SysCtl.interval++;
						Close_Socket(&SysCtl.Sockfd);
					}
					else
					{
						SysCtl.interval = 0;
						Delay(0, 10);
					}
				}
				else
					Socket_Err_Coding();
			}
			default:
				SysCtl.interval = 0;
				Delay(0, 10);
				break;
		}
	}

	pthread_exit(0);

	return NULL;
}

int Step_Init(void)
{
	DBUG( "Aplication_init:success!\n");
	SysCtl.TT_cnt = 0;//add by lk 20150611
	SysCtl.Apdu_Cnt = 0;//add by yyh 20150825
	//SetCWL_Sta(CWL_INIT);
	HB_Init();
	//GetApkVersion();

	//Set_VSIM_ANL_StateMacine(VSIM_ANL_REMOVE);

	return 0;
}

void *RecvAndroidThread(void *arg)
{
	int socketfd = 0;
	int temp_len = 0;
	int cnt = 0;
	int num = 0;
	int deal_num = 0;
	unsigned int CMD = 0;
	unsigned char TTRecvBuf[128];
	unsigned char Value[128] = {0};
	int minute_Remain = -1;
	TD_ComProtocl_RecvFrame_t *p_Recv = NULL;
	//unsigned char atr[] = {0x3B, 0x9D, 0x95, 0x80, 0x1F, 0xC7, 0x80, 0x31, 0xE0, 0x73, 0xFE, 0x21, 0x13, 0x65, 0x15, 0x09, 0x63, 0x86, 0x83, 0xA1};

    DBUG("connecting to %s:%d", SysCtl.ServerInfo.IP[3], SysCtl.ServerInfo.Port[3]);
	Data.Android_Socket_fd = ConnectServer(SysCtl.ServerInfo.IP[3], SysCtl.ServerInfo.Port[3]);
	if(Data.Android_Socket_fd <= 0) //connect fail
	{
		DBUG( "connect to %s:%d  Error!!!\n", SysCtl.ServerInfo.IP[3], SysCtl.ServerInfo.Port[3]);
		return NULL;
	}
	DBUG(  "Connect server %s:%d success !!!!\n", SysCtl.ServerInfo.IP[3], SysCtl.ServerInfo.Port[3], Data.Android_Socket_fd);


    VUSIM_init();
    VUSIM_ATR(); //发送ATR到android上层，也就是插卡
    Data.VUSIM_Global.APDU_STAGE = 1;

	while(1)
	{
		memset(TTRecvBuf, 0, sizeof(TTRecvBuf));
		temp_len = recv(Data.Android_Socket_fd, TTRecvBuf, sizeof(TTRecvBuf), MSG_DONTWAIT);
		if(temp_len > 0)
		{
			//PrintDebuf("APDU:", TTRecvBuf, temp_len);
			VisulSimProccess(TTRecvBuf, temp_len);
		}
		else if(0 == temp_len)
		{
			DBUG( "This come from %s:%d, temp_len is %d, err is %d:%s\n", __func__, __LINE__, temp_len, errno, strerror(errno));
			Close_Socket(&SysCtl.Sockfd);
		}
		else
		{
			//DBUG( "This come from %s:%d, temp_len is %d, err is %d:%s   exit\n", __func__, __LINE__, temp_len, errno, strerror(errno));
			//exit(-1);
		}

	}

	return NULL;
}

void SimFileRequest(void)
{
    while(1)
    {
        AplicationConnectToServer();
        //AccessAuth_Info_Prepare(&SysCtl.AA_Info);
        AplicationAuthWithServer(SysCtl.Sockfd, &(SysCtl.AA_Info), &SysCtl.AA_Result);
        AplicationAutoDialerNumGet(SysCtl.Sockfd, &SysCtl.AA_Result, &SysCtl);
        AplicationGetAPNinfo(SysCtl.Sockfd, &SysCtl); //这里的 SysCtl.APN_Info 需要发送到上层android设置到手机设置里
        AplicationGetMSNinfo(SysCtl.Sockfd, &SysCtl);
        AplicationLocalFileUpdate(SysCtl.Sockfd, &SysCtl.AA_Result);
        AplicationProtocolANL_Prepare(&SysCtl.AA_Result, SysCtl.AA_Info.SN);//modify by 20160819, add para SN
        //HeartBeat_Main();
		SysCtl.Step = 8;
        break;  //判断SIM卡数据准备是否准备ok，准备好数据就可以跳出while（1）
    }
}


void Thread_Create(void)
{
    SimFileRequest();
    DBUG("--------------------------------------------------------------");
    sleep(5);
	Creat_New_Thread((void *)SocketSendThread);
	Creat_New_Thread((void *)SocketRecvThread);
	//ISO7816_ANL_Thread_Create();
	Creat_New_Thread((void *)RecvAndroidThread);

	return ;
}

void InitSysCtlStruct(const char* domainName, const char* ip, uint16_t port)
{
	memset((&SysCtl), 0, sizeof(Sys_Ctl_t));

	SysCtl.AA_Info.FirmwareVer = FirmWareVersion;
	//SetNetConfig();
	memcpy(SysCtl.ServerInfo.IP[0], DefaultIP_Addr, strlen(DefaultIP_Addr));
	memcpy(SysCtl.ServerInfo.IP[1], DefaultLog_Addr, strlen(DefaultLog_Addr));
	memcpy(SysCtl.ServerInfo.IP[2], Defaultupdate_Addr, strlen(Defaultupdate_Addr));
	memcpy(SysCtl.ServerInfo.IP[3], Android_Addr, strlen(Android_Addr));

	SysCtl.ServerInfo.Port[0] = DefaultPort;
	SysCtl.ServerInfo.Port[1] = DefaultLogPort;
	SysCtl.ServerInfo.Port[2] = DefaultUpdatePort;
	SysCtl.ServerInfo.Port[3] = AndroidPort;

	strcpy(SysCtl.ServerInfo.domainName , domainName);
	strcpy(SysCtl.ServerInfo.IP[0] , ip);
	SysCtl.ServerInfo.Port[0]=port;

    strcpy(SysCtl.sICCID, "123456789");

	SysCtl.AA_Info.MCC = 460;
	SysCtl.AA_Info.MNC = 01;
	SysCtl.AA_Info.CID = 01;
	SysCtl.AA_Info.LAC = 00;
	SysCtl.AA_Info.FirmwareVer = 123123123;
	SysCtl.AA_Info.MIP_ListVer = 123;
	strcpy(SysCtl.AA_Info.SN, "860172008002126");
	SysCtl.AA_Info.vir_flag='a';
	memset(SysCtl.AA_Info.take_time, 0, 2);
	strcpy(SysCtl.AA_Info.versionAPK, "versionAPK");
	memcpy(SysCtl.AA_Info.LastIMSI, "12563", 4);
	SysCtl.Battery = 100;
	SysCtl.AA_Info.Battery = 100;

	SysCtl.LocMod.DataUsed = 1024*100;
	unsigned short DataUsed = (unsigned short)(SysCtl.LocMod.DataUsed / 1024);
	memcpy(&SysCtl.AA_Info.Data_Size, &DataUsed, sizeof(unsigned short));
}

int Xm_Data_Init(const char* domainName, const char* ip, uint16_t port)
{
    DBUG("***Running Firmware version is %ld!***\n", FirmWareVersion);
	memset((&SysCtl), 0, sizeof(Sys_Ctl_t));
	memset((&Data), 0, sizeof(Data));

	InitSysCtlStruct(domainName, ip, port);
	return 0;
}
extern atomic_int exit_flag = 0;
 static void s_on_exit(int sig)
 {
     exit_flag = 1;
     DBUG("exiting .....");
 }
int start_main()
{
    Thread_Create();
    // setting exit signal function
    signal(SIGINT, s_on_exit);
    while (!exit_flag)
    {
        sleep(1);
    }
}

int main(void)
{
	Xm_Data_Init("1563u62n39.51mypc.cn","103.46.128.21", 39395);
    start_main();
	return 0;
}


